package com.herench.bridge.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.herench.bridge.PayService;
import com.herench.bridge.StrangeMessage;
import com.herench.bridge.utils.DesUtil;
import com.herench.bridge.utils.HttpClientSupport;
import com.herench.bridge.utils.MD5Util;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;

/**
 * 支付服务
 * Created by ThinkPad on 2018/6/4.
 */

@Component("payService")
@javax.jws.WebService(endpointInterface = "com.herench.bridge.PayService", serviceName = "payService", targetNamespace = "http://bridge.herench.com/")
public class PayServiceImpl2 implements PayService {

    private static final Logger logger = Logger.getLogger(PayServiceImpl2.class);

    @Value("${payUrl}")
    private String payUrl;


    @Override
    public String qrPay(String message) {
        logger.info("request:" + message);
        StrangeMessage responseMessage = new StrangeMessage();
        responseMessage.addAttrToClientInfo("METHOD", "qrPay");
        try {
            StrangeMessage requestMessage = new StrangeMessage(message);
            String channelCode = requestMessage.getAttrFromCommitDataRow("CHANNEL_CODE");
            Assert.hasLength(channelCode, "CHANNEL_CODE 为空");
            String idCard = requestMessage.getAttrFromCommitDataRow("ID_CARD");
//            Assert.hasLength(idCard, "ID_CARD 为空");
            String phone = requestMessage.getAttrFromCommitDataRow("PHONE");
//            Assert.hasLength(phone, "PHONE 为空");
            String bsType = requestMessage.getAttrFromCommitDataRow("BS_TYPE");
//            Assert.hasLength(bsType, "BS_TYPE 为空");
            String subject = requestMessage.getAttrFromCommitDataRow("SUBJECT");
            Assert.hasLength(subject, "SUBJECT 为空");
            String name = requestMessage.getAttrFromCommitDataRow("NAME");
//            Assert.hasLength(name, "NAME 为空");
            String outTradeNo = requestMessage.getAttrFromCommitDataRow("OUT_TRADE_NO");
            Assert.hasLength(outTradeNo, "OUT_TRADE_NO 为空");
            String timeoutExpress = requestMessage.getAttrFromCommitDataRow("TIMEOUT_EXPRESS");
            Assert.hasLength(timeoutExpress, "TIMEOUT_EXPRESS 为空");
            String transIntroduce = requestMessage.getAttrFromCommitDataRow("TRANS_INTRODUCE");
//            Assert.hasLength(transIntroduce, "TRANS_INTRODUCE 为空");
            String totalAmount = requestMessage.getAttrFromCommitDataRow("TOTAL_AMOUNT");
            Assert.hasLength(totalAmount, "TOTAL_AMOUNT 为空");
            String timeStart = requestMessage.getAttrFromCommitDataRow("TIME_START");
            Assert.hasLength(timeStart, "TIME_START 为空");
            String deptCode = requestMessage.getAttrFromCommitDataRow("DEPT_CODE");
            String doctorCode = requestMessage.getAttrFromCommitDataRow("DOCTOR_CODE");
            String transDetail = requestMessage.getAttrFromCommitDataRow("TRANS_DETAIL");
            String deviceInfo = requestMessage.getAttrFromCommitDataRow("DEVICE_INFO");
            Assert.hasLength(deviceInfo, "DEVICE_INFO 为空");
            String sign = requestMessage.getAttrFromCommitDataRow("SIGN");
            Map<String, Object> params = new HashMap<>();
            params.put("channelCode", channelCode);
            params.put("idCard", idCard);
            params.put("phone", phone);
            params.put("bsType", bsType);
            params.put("subject", subject);
            params.put("name", name);
            params.put("outTradeNo", outTradeNo);
            params.put("timeoutExpress", timeoutExpress);
            params.put("transIntroduce", transIntroduce);
            params.put("totalAmount", totalAmount);
            params.put("timeStart", timeStart);
            params.put("deptCode", deptCode);
            params.put("doctorCode", doctorCode);
            params.put("transDetail", transDetail);
            params.put("deviceInfo", deviceInfo);
            params.put("sign", sign);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("funcode", "700001");
            jsonObject.put("token", "token");
            jsonObject.put("args", DesUtil.encrypt(JSON.toJSONString(params)));
            String str = HttpClientSupport.doPost(payUrl, jsonObject.toString(), "UTF-8");
            JSONObject resJson = JSON.parseObject(str);
            responseMessage.addExecuteStatus(resJson.getString("code"));
            responseMessage.addExecuteMessage(resJson.getString("message"));

            if (resJson.getString("code").equals("0")) {
                JSONObject data = resJson.getJSONObject("data");
                responseMessage.addAttrToReturnData("TOTAL_AMOUNT", data.getString("totalAmount"));
                responseMessage.addAttrToReturnData("CODE_URL", data.getString("codeUrl"));
                responseMessage.addAttrToReturnData("TIME_START", data.getString("timeStart"));
                responseMessage.addAttrToReturnData("TRADE_NO", data.getString("tradeNo"));
                responseMessage.addAttrToReturnData("OUT_TRADE_NO", data.getString("outTradeNo"));
                responseMessage.addAttrToReturnData("PHONE", data.getString("phone"));
                responseMessage.addAttrToReturnData("ID_CARD", data.getString("idCard"));
                responseMessage.addAttrToReturnData("TRADE_NO", data.getString("tradeNo"));
                responseMessage.addAttrToReturnData("SIGN", data.getString("sign"));
                responseMessage.addAttrToReturnData("PAY_URL", data.getString("payUrl"));
                responseMessage.addAttrToReturnData("BS_TYPE", data.getString("bsType"));
            }

        } catch (Exception e) {
            responseMessage.addExecuteStatus("1");
            if (e.getMessage() == null) {
                responseMessage.addExecuteMessage("请求超时，请重试！");
            } else {
                responseMessage.addExecuteMessage(e.getMessage());
            }
            logger.info("异常信息:" + e.getCause());
            e.printStackTrace();
        }
        logger.info("response:" + responseMessage);
        return responseMessage.getBody().asXML();
    }


    @Override
    public String authCodePay(String message) {
        logger.info("request:" + message);
        StrangeMessage responseMessage = new StrangeMessage();
        responseMessage.addAttrToClientInfo("METHOD", "authCodePay");
        try {
            StrangeMessage requestMessage = new StrangeMessage(message);
            String channelCode = requestMessage.getAttrFromCommitDataRow("CHANNEL_CODE");
            Assert.hasLength(channelCode, "CHANNEL_CODE 为空");
            String idCard = requestMessage.getAttrFromCommitDataRow("ID_CARD");
//            Assert.hasLength(idCard, "ID_CARD 为空");
            String phone = requestMessage.getAttrFromCommitDataRow("PHONE");
//            Assert.hasLength(phone, "PHONE 为空");
            String authCode = requestMessage.getAttrFromCommitDataRow("AUTH_CODE");
            Assert.hasLength(authCode, "AUTH_CODE 为空");
            String bsType = requestMessage.getAttrFromCommitDataRow("BS_TYPE");
//            Assert.hasLength(bsType, "BS_TYPE 为空");
            String subject = requestMessage.getAttrFromCommitDataRow("SUBJECT");
            Assert.hasLength(subject, "SUBJECT 为空");
            String name = requestMessage.getAttrFromCommitDataRow("NAME");
//            Assert.hasLength(name, "NAME 为空");
            String outTradeNo = requestMessage.getAttrFromCommitDataRow("OUT_TRADE_NO");
            Assert.hasLength(outTradeNo, "OUT_TRADE_NO 为空");
            String timeoutExpress = requestMessage.getAttrFromCommitDataRow("TIMEOUT_EXPRESS");
            Assert.hasLength(timeoutExpress, "TIMEOUT_EXPRESS 为空");
            String transIntroduce = requestMessage.getAttrFromCommitDataRow("TRANS_INTRODUCE");
//            Assert.hasLength(transIntroduce, "TRANS_INTRODUCE 为空");
            String totalAmount = requestMessage.getAttrFromCommitDataRow("TOTAL_AMOUNT");
            Assert.hasLength(totalAmount, "TOTAL_AMOUNT 为空");
            String timeStart = requestMessage.getAttrFromCommitDataRow("TIME_START");
            Assert.hasLength(timeStart, "TIME_START 为空");
            String deptCode = requestMessage.getAttrFromCommitDataRow("DEPT_CODE");
            String doctorCode = requestMessage.getAttrFromCommitDataRow("DOCTOR_CODE");
            String transDetail = requestMessage.getAttrFromCommitDataRow("TRANS_DETAIL");
            String deviceInfo = requestMessage.getAttrFromCommitDataRow("DEVICE_INFO");
            Assert.hasLength(deviceInfo, "DEVICE_INFO 为空");
            String sign = requestMessage.getAttrFromCommitDataRow("SIGN");
            Map<String, Object> params = new HashMap<>();
            params.put("channelCode", channelCode);
            params.put("idCard", idCard);
            params.put("phone", phone);
            params.put("bsType", bsType);
            params.put("subject", subject);
            params.put("name", name);
            params.put("outTradeNo", outTradeNo);
            params.put("timeoutExpress", timeoutExpress);
            params.put("transIntroduce", transIntroduce);
            params.put("totalAmount", totalAmount);
            params.put("timeStart", timeStart);
            params.put("deptCode", deptCode);
            params.put("doctorCode", doctorCode);
            params.put("transDetail", transDetail);
            params.put("deviceInfo", deviceInfo);
            params.put("authCode",authCode);
            params.put("sign", sign);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("funcode", "700002");
            jsonObject.put("token", "token");
            jsonObject.put("args", DesUtil.encrypt(JSON.toJSONString(params)));
            String str = HttpClientSupport.doPost(payUrl, jsonObject.toString(), "UTF-8");
            JSONObject resJson = JSON.parseObject(str);
            responseMessage.addExecuteStatus(resJson.getString("code"));
            responseMessage.addExecuteMessage(resJson.getString("message"));

            if (resJson.getString("code").equals("0") || resJson.getString("code").equals("1") || resJson.getString("code").equals("5")) {
                JSONObject data = resJson.getJSONObject("data");
                responseMessage.addAttrToReturnData("TRADE_STATE_DESC", data.getString("tradeStateDesc"));
                responseMessage.addAttrToReturnData("TOTAL_AMOUNT", data.getString("totalAmount"));
                responseMessage.addAttrToReturnData("TIME_START", data.getString("timeStart"));
                responseMessage.addAttrToReturnData("TRADE_NO", data.getString("tradeNo"));
                responseMessage.addAttrToReturnData("PHONE", data.getString("phone"));
                responseMessage.addAttrToReturnData("OUT_TRADE_NO", data.getString("outTradeNo"));
                responseMessage.addAttrToReturnData("ID_CARD", data.getString("idCard"));
                responseMessage.addAttrToReturnData("SIGN", data.getString("sign"));
                responseMessage.addAttrToReturnData("BS_TYPE", data.getString("bsType"));
                responseMessage.addAttrToReturnData("TRADE_STATE", data.getString("tradeState"));
            }

        } catch (Exception e) {
            responseMessage.addExecuteStatus("1");
            if (e.getMessage() == null) {
                responseMessage.addExecuteMessage("请求超时，请重试！");
            } else {
                responseMessage.addExecuteMessage(e.getMessage());
            }
            logger.info("异常信息:" + e.getCause());
            e.printStackTrace();
        }
        logger.info("response:" + responseMessage);
        return responseMessage.getBody().asXML();
    }

    @Override
    public String query(String message) {
        logger.info("request:" + message);
        StrangeMessage responseMessage = new StrangeMessage();
        responseMessage.addAttrToClientInfo("METHOD", "query");
        try {
            StrangeMessage requestMessage = new StrangeMessage(message);
            String channelCode = requestMessage.getAttrFromCommitDataRow("CHANNEL_CODE");
            Assert.hasLength(channelCode, "CHANNEL_CODE 为空");

            String tradeNo = requestMessage.getAttrFromCommitDataRow("TRADE_NO");
            Assert.hasLength(tradeNo, "TRADE_NO 为空");
            String deviceInfo = requestMessage.getAttrFromCommitDataRow("DEVICE_INFO");
//            Assert.hasLength(deviceInfo, "DEVICE_INFO 为空");
            String sign = requestMessage.getAttrFromCommitDataRow("SIGN");
            Map<String, Object> params = new HashMap<>();
            params.put("channelCode", channelCode);
            params.put("tradeNo", tradeNo);
            params.put("deviceInfo", deviceInfo);
            params.put("sign", sign);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("funcode", "720001");
            jsonObject.put("token", "token");
            jsonObject.put("args", DesUtil.encrypt(JSON.toJSONString(params)));
            String str = HttpClientSupport.doPost(payUrl, jsonObject.toString(), "UTF-8");
            JSONObject resJson = JSON.parseObject(str);
            responseMessage.addExecuteStatus(resJson.getString("code"));
            responseMessage.addExecuteMessage(resJson.getString("message"));

            if (resJson.getString("code").equals("0")) {
                JSONObject data = resJson.getJSONObject("data");
                responseMessage.addAttrToReturnData("TRADE_STATE_DESC", data.getString("tradeStateDesc"));
                responseMessage.addAttrToReturnData("TRADE_STATE", data.getString("tradeState"));
                responseMessage.addAttrToReturnData("TRADE_NO", data.getString("tradeNo"));
                responseMessage.addAttrToReturnData("SIGN", data.getString("sign"));
            }

        } catch (Exception e) {
            responseMessage.addExecuteStatus("1");
            if (e.getMessage() == null) {
                responseMessage.addExecuteMessage("请求超时，请重试！");
            } else {
                responseMessage.addExecuteMessage(e.getMessage());
            }
            logger.info("异常信息:" + e.getCause());
            e.printStackTrace();
        }
        logger.info("response:" + responseMessage);
        return responseMessage.getBody().asXML();
    }

    @Override
    public String refunds(String message) {
        logger.info("request:" + message);
        StrangeMessage responseMessage = new StrangeMessage();
        responseMessage.addAttrToClientInfo("METHOD", "refunds");
        try {
            StrangeMessage requestMessage = new StrangeMessage(message);
            String channelCode = requestMessage.getAttrFromCommitDataRow("CHANNEL_CODE");
            Assert.hasLength(channelCode, "CHANNEL_CODE 为空");
            String tradeNo = requestMessage.getAttrFromCommitDataRow("TRADE_NO");
            Assert.hasLength(tradeNo, "TRADE_NO 为空");
            String totalAmount = requestMessage.getAttrFromCommitDataRow("TOTAL_AMOUNT");
            Assert.hasLength(totalAmount, "TOTAL_AMOUNT 为空");
            String refundTime = requestMessage.getAttrFromCommitDataRow("REFUND_TIME");
            Assert.hasLength(refundTime, "REFUND_TIME 为空");
            String deviceInfo = requestMessage.getAttrFromCommitDataRow("DEVICE_INFO");
//            Assert.hasLength(deviceInfo, "DEVICE_INFO 为空");
            String refundDesc = requestMessage.getAttrFromCommitDataRow("REFUND_DESC");
            Assert.hasLength(refundDesc, "REFUND_DESC 为空");
            String sign = requestMessage.getAttrFromCommitDataRow("SIGN");
            Map<String, Object> params = new HashMap<>();
            params.put("channelCode", channelCode);
            params.put("tradeNo", tradeNo);
            params.put("totalAmount", totalAmount);
            params.put("refundTime", refundTime);
            params.put("deviceInfo", deviceInfo);
            params.put("refundDesc", refundDesc);
            params.put("sign", sign);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("funcode", "710001");
            jsonObject.put("token", "token");
            jsonObject.put("args", DesUtil.encrypt(JSON.toJSONString(params)));

            new Thread(new Runnable() {
                @Override
                public void run() {
                    String str = null;
                    try {
                        str = HttpClientSupport.doPost(payUrl, jsonObject.toString(), "UTF-8");
                    } catch (Exception e) {
                        logger.info("调用第一次请求异常信息:" + str);
                        try {
                            str = HttpClientSupport.doPost(payUrl, jsonObject.toString(), "UTF-8");
                        } catch (Exception e1) {
                            logger.info("第二次请求异常信息:" + str);
                            try {
                                str = HttpClientSupport.doPost(payUrl, jsonObject.toString(), "UTF-8");
                            } catch (Exception e2) {
                                logger.info("第三次请求异常信息:" + str);
                                e2.printStackTrace();
                            }
                        }
                    }
                    JSONObject resJson = JSON.parseObject(str);
                    logger.info("response message:" + resJson);
                }
            }).start();

            responseMessage.addExecuteStatus("0");
            responseMessage.addExecuteMessage("退费请求已接收");
            responseMessage.addAttrToReturnData("TRADE_NO", totalAmount);
            responseMessage.addAttrToReturnData("REFUND_AMOUNT", totalAmount);
            responseMessage.addAttrToReturnData("SIGN", MD5Util.string2MD5(responseMessage.getBody().asXML()));


        } catch (Exception e) {
            responseMessage.addExecuteStatus("1");
            if (e.getMessage() == null) {
                responseMessage.addExecuteMessage("请求超时，请重试！");
            } else {
                responseMessage.addExecuteMessage(e.getMessage());
            }
            logger.info("异常信息:" + e.getCause());
            e.printStackTrace();
        }
        logger.info("response:" + responseMessage);
        return responseMessage.getBody().asXML();
    }


    @Override
    public String partRefunds(String message) {
        logger.info("request:" + message);
        StrangeMessage responseMessage = new StrangeMessage();
        responseMessage.addAttrToClientInfo("METHOD", "partRefunds");
        try {
            StrangeMessage requestMessage = new StrangeMessage(message);
            String channelCode = requestMessage.getAttrFromCommitDataRow("CHANNEL_CODE");
            Assert.hasLength(channelCode, "CHANNEL_CODE 为空");
            String tradeNo = requestMessage.getAttrFromCommitDataRow("TRADE_NO");
            String transactionId = requestMessage.getAttrFromCommitDataRow("TRANSACTION_ID");
            Assert.isTrue(StringUtils.hasLength(tradeNo) || StringUtils.hasLength(transactionId), "TRADE_NO 和 TRANSACTION_ID不能同时为空");
            String totalAmount = requestMessage.getAttrFromCommitDataRow("TOTAL_AMOUNT");
            Assert.hasLength(totalAmount, "TOTAL_AMOUNT 为空");
            String refundAmount = requestMessage.getAttrFromCommitDataRow("REFUND_AMOUNT");
            Assert.hasLength(totalAmount, "REFUND_AMOUNT 为空");
            String outRequestNo = requestMessage.getAttrFromCommitDataRow("OUT_REQUEST_NO");
            Assert.hasLength(outRequestNo, "OUT_REQUEST_NO 为空");
            String refundTime = requestMessage.getAttrFromCommitDataRow("REFUND_TIME");
            Assert.hasLength(refundTime, "REFUND_TIME 为空");
            String deviceInfo = requestMessage.getAttrFromCommitDataRow("DEVICE_INFO");
//            Assert.hasLength(deviceInfo, "DEVICE_INFO 为空");
            String refundDesc = requestMessage.getAttrFromCommitDataRow("REFUND_DESC");
            Assert.hasLength(refundDesc, "REFUND_DESC 为空");
            String sign = requestMessage.getAttrFromCommitDataRow("SIGN");
            Map<String, Object> params = new HashMap<>();
            params.put("channelCode", channelCode);
            if (StringUtils.hasLength(tradeNo)){
                params.put("tradeNo", tradeNo);
            }else {
                params.put("transactionId",transactionId);
            }
            params.put("totalAmount", totalAmount);
            params.put("refundTime", refundTime);
            params.put("refundAmount", refundAmount);
            params.put("outRequestNo", outRequestNo);
            params.put("deviceInfo", deviceInfo);
            params.put("refundDesc", refundDesc);
            params.put("sign", sign);
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("funcode", "710002");
            jsonObject.put("token", "token");
            jsonObject.put("args", DesUtil.encrypt(JSON.toJSONString(params)));
            String str = null;

            str = HttpClientSupport.doPost(payUrl, jsonObject.toString(), "UTF-8");
            logger.info("原报文返回:" + str);
            JSONObject resJson = JSON.parseObject(str);
            logger.info("response message:" + resJson);
            responseMessage.addExecuteStatus(resJson.getString("code"));
            responseMessage.addExecuteMessage(resJson.getString("message"));

            if (resJson.getString("code").equals("0")) {
                JSONObject data = resJson.getJSONObject("data");
                responseMessage.addAttrToReturnData("REFUND_AMOUNT", data.getString("refundAmount"));
                responseMessage.addAttrToReturnData("OUT_REQUEST_NO", data.getString("outRequestNo"));
                responseMessage.addAttrToReturnData("TRADE_NO", data.getString("tradeNo"));
                responseMessage.addAttrToReturnData("SIGN", data.getString("sign"));
            }

        } catch (Exception e) {
            responseMessage.addExecuteStatus("1");
            if (e.getMessage() == null) {
                responseMessage.addExecuteMessage("请求超时，请重试！");
            } else {
                responseMessage.addExecuteMessage(e.getMessage());
            }
            logger.info("异常信息:" + e.getCause());
            e.printStackTrace();
        }
        logger.info("response:" + responseMessage);
        return responseMessage.getBody().asXML();
    }
}
